package src.dp.stock;

public class no121 {//买卖股票的最佳时机

    /**
     * 1. dp数组下标含义：
     * dp[i][0]:第 i 天持有股票所得的最大现金，只是表示第 i 天持有，不一定非是这一天买入，只表示一个持有的状态
     * dp[i][1]:第 i 天不持有股票所得的最大现金，最终在dp[num-1][0] dp[num-1][1]中取max
     *
     * 2. 递推公式：
     * dp[i][0] = Math.max(dp[i - 1][0], -prices[i])
     * dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i])
     *
     * 3. 初始化数组：dp[0][0] = -prices[0];  dp[0][1] = 0
     * 4. 遍历顺序：从前到后
     */
    public int maxProfit(int[] prices) {
        int len = prices.length;
        int[][] dp = new int[2][2];

        dp[0][0] = -prices[0];
        dp[0][1] = 0;

        //dp[i]只是依赖于dp[i - 1]的状态,只需要记录 当前天的dp状态和前一天的dp状态就可以了，可以使用滚动数组来节省空间
        for (int i = 1; i < len; i++) {
            dp[i % 2][0] = Math.max(dp[(i - 1) % 2][0], -prices[i]);
            dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], prices[i] + dp[(i - 1) % 2][0]);
        }
        return dp[(len - 1) % 2][1];
    }

    public int maxProfit2(int[] prices) {
        int len = prices.length;
        int[][] dp = new int[len][2];

        dp[0][0] = -prices[0];
        dp[0][1] = 0;

        for (int i = 1; i < len; i++) {
            //第i天持有股票分两种情况，1、第i-1天就持有  2、前i-1天没买，第i天买所以钱是-prices[i]
            dp[i][0] = Math.max(dp[i - 1][0], -prices[i]);
            //第i不天持有股票分两种情况，1、第i-1天就不持有  2、前i-1天持有，第i天卖出
            dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i]);

        }
        //因为最后股票一定卖出了 所以为不持有股票，所以是dp[len-1][1]，而不用选dp[len-1][1]和dp[len-1][0]的最大值
        return dp[len - 1][1];
    }


}
